package com.yiduo.outpost.core.web.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.util.ClassUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author yanwen
 */
@Slf4j
public class ExceptionHandlerChain {

    private static final List<ExceptionTranslator> EXCEPTION_TRANSLATORS = new ArrayList<>();

    static {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        EXCEPTION_TRANSLATORS.add(new RestExceptionTranslator());
        if (ClassUtils.isPresent("org.springframework.web.bind.MethodArgumentNotValidException", classLoader)) {
            EXCEPTION_TRANSLATORS.add(new MethodArgumentNotValidExceptionTranslator());
        }
        if (ClassUtils.isPresent("org.springframework.dao.DuplicateKeyException", classLoader)) {
            EXCEPTION_TRANSLATORS.add(new DuplicateKeyExceptionTranslator());
        }
        EXCEPTION_TRANSLATORS.add(new SecurityExceptionTranslator());
        EXCEPTION_TRANSLATORS.add(new NullableExceptionTranslator());
        EXCEPTION_TRANSLATORS.add(new ConnectExceptionTranslator());
        EXCEPTION_TRANSLATORS.add(new ServerErrorExceptionTranslator());
    }

    public static String determineErrorMessage(MessageSource messageSource, Throwable error) {

        for (ExceptionTranslator exceptionTranslator : EXCEPTION_TRANSLATORS) {
            if (exceptionTranslator.support(error)) {
                return exceptionTranslator.translateException(error, messageSource);
            }
        }
        return null;
    }

    /**
     * 请求参数异常，封装异常消息
     * @param messageSource
     * @param error
     * @return
     */
    public static Map<String, Object> determineErrorField(MessageSource messageSource, Throwable error) {
        for (ExceptionTranslator exceptionTranslator : EXCEPTION_TRANSLATORS) {
            if (exceptionTranslator.supportFiled(error)) {
                return exceptionTranslator.translateExceptionFiled(error, messageSource);
            }
        }
        return null;
    }

}
